package com.rongji.dfish.ui;
//package com.rongji.dfish.xmltmpl3;
//
//import java.lang.annotation.Annotation;
//import java.lang.reflect.Field;
//import java.lang.reflect.Method;
//import java.lang.reflect.Modifier;
//import java.text.DecimalFormat;
//import java.text.SimpleDateFormat;
//import java.util.ArrayList;
//import java.util.Arrays;
//import java.util.Collection;
//import java.util.Collections;
//import java.util.Date;
//import java.util.HashMap;
//import java.util.HashSet;
//import java.util.List;
//import java.util.Map;
//import java.util.Set;
//import java.util.TreeSet;
//import java.util.Map.Entry;
//
//import com.rongji.dfish.base.Utils;
//import com.rongji.dfish.xmltmpl3.annotation.Disabled;
//import com.rongji.dfish.xmltmpl3.annotation.FormElementType;
//import com.rongji.dfish.xmltmpl3.annotation.Format;
//import com.rongji.dfish.xmltmpl3.annotation.GridPosition;
//import com.rongji.dfish.xmltmpl3.annotation.PropInfo;
//import com.rongji.dfish.xmltmpl3.annotation.Readonly;
//import com.rongji.dfish.xmltmpl3.annotation.validation.Decimal;
//import com.rongji.dfish.xmltmpl3.annotation.validation.Length;
//import com.rongji.dfish.xmltmpl3.annotation.validation.NotNull;
//import com.rongji.dfish.xmltmpl3.annotation.validation.Pattern;
//import com.rongji.dfish.xmltmpl3.annotation.validation.Size;
//import com.rongji.dfish.xmltmpl3.annotation.validation.Time;
//import com.rongji.dfish.xmltmpl3.form.DatePicker;
//import com.rongji.dfish.xmltmpl3.form.Spinner;
//import com.rongji.dfish.xmltmpl3.form.Text;
//import com.rongji.dfish.xmltmpl3.form.Textarea;
//
///**
// * 
// * AnnotationUtils 用JDK5.0以及以后版本提供的注解，简化开发。
// * <p>它可以让一些原来需要写代码的工作，现在可以通过写注解来完成。
// * 写注解的话，有大量默认值，并且绑定表单和列表，以及提交数据时，都可以重复利用Bean的注解。
// * 可以有效的减少编码量。</p>
// * 
// * @author DFish Team
// * @since DFish 2.4
// *
// */
//public class AnnotationUtils {
//
//	/**
//	 * 根据bean的类中的注解把bean中的内容填充到表单里面去，
//	 * <p>
//	 * 如果指定propNames不为空则只绑定这些属性，这个属性名是指javaBean中的属性名，不是表单名.
//	 * 如果这个form中已经含有相关表单元素，那么将不再重新创建一个，而是把值，校验，格式等信息绑定到原有元素中去。
//	 * 但如果是HIDDEN或LABEL不绑定校验。
//	 * </p>
//	 * <p>
//	 * 典型用法：
//	 * </p>
//	 * <ul>
//	 * <li>自动生成的布局代码，进行数值绑定和校验绑定</li>
//	 * <li>生成空白表单</li>
//	 * <li>追加表单</li>
//	 * </ul>
//	 * 
//	 * @param form
//	 *            FormPanel
//	 * @param bean
//	 *            Object
//	 * @param propNames
//	 *            如果指定的属性名不为空则只绑定这些属性
//	 */
//	public static void bind(FormPanel form, Object bean, String... propNames) {
//		if (bean == null)
//			return;
//		HashSet<String> limitProps = null;
//		if (propNames != null && propNames.length > 0) {
//			limitProps = new HashSet<String>(Arrays.asList(propNames));
//		}
//		List<Map.Entry<String, Annotation[]>> properties = sortProperties(bean
//				.getClass());
//		for (Map.Entry<String, Annotation[]> entry : properties) {
//			if (limitProps != null && !limitProps.contains(entry.getKey())) {
//				continue;
//			}
//			PropInfo info = getAnnotation(entry.getValue(), PropInfo.class);
//			FormElement<?> fe = null;
//			if (info != null) {
//				String formElmentName = info.name();
//				if (formElmentName == null || formElmentName.equals("")) {
//					formElmentName = entry.getKey();
//				}
//				// 每个PropInfo 如果它已经有formElement，那么设置值，格式，和校验信息
//				fe = form.findSingleElementByName(formElmentName);
//				// 如果没有新增加一个formElement
//				if (fe == null) {
//					// 新增属性
//					FormElementType t = info.formType();
//					Class<?> c = getPropType(bean.getClass(), entry.getKey());
//					if (t == FormElementType.AUTO) {
//						// 自动决定属性
//						if (Date.class.isAssignableFrom(c)) {
//							t = FormElementType.DATEPICKER;
//						} else if (Number.class.isAssignableFrom(c)
//								|| int.class == c || long.class == c
//								|| short.class == c || double.class == c
//								|| float.class == c) {
//							t = FormElementType.SPINNER;
//						} else {
//							t = FormElementType.TEXT;
//						}
//					}
//
//					switch (t) {
//					case AUTO:
//						break;
//					case TEXT:
//						fe = new Text(formElmentName, info.title(), null, -1);
//						break;
//					case TEXTAREA:
//						fe = new Textarea(formElmentName, info.title(), null,
//								-1);
//						break;
//					case SPINNER:
//						fe = new Spinner(formElmentName, info.title(), null,
//								null, null, new Double(1.0));
//						break;
//					case DATEPICKER:
//						Format format = getAnnotation(entry.getValue(),
//								Format.class);
//						int formatValue = DatePicker.DATE_TIME_FULL;
//						if (format != null) {
//							String formatStr = format.formFormat();
//							if (formatStr == null || formatStr.equals("")) {
//								formatStr = format.format();
//							}
//							if ("yyyy-MM-dd".equals(formatStr)) {
//								formatValue = DatePicker.DATE;
//							} else if ("yyyy-MM-dd HH:mm".equals(formatStr)) {
//								formatValue = DatePicker.DATE_TIME;
//							}
//						}
//						fe = new DatePicker(formElmentName, info.title(), null,
//								formatValue);
//						break;
//
//					case HIDDEN:
//						fe = new Hidden(formElmentName, null);
//						break;
//					case LABEL:
//						fe = new Label(formElmentName, info.title(), null);
//						break;
//					}
//					form.add(fe);
//				}
//			} else {
//				// 如果PropInfo信息没有的话。
//				fe = form.findSingleElementByName(entry.getKey());
//				// 没有设置PropInfo的属性，由于不能确定其位置不能自动添加，但是可以设置值和校验信息
//				if (fe == null) {
//					fe = new Hidden(entry.getKey(), null);
//					form.add(fe);
//				}
//			}
//			if (fe != null) {
//				setAnnotation(fe, bean, entry.getKey(), entry.getValue());
//			}
//		}
//
//	}
//
//	private static List<Map.Entry<String, Annotation[]>> sortProperties(
//			Class<?> clz) {
//		// 找到所有带PropInfo的属性。没带PropInfo的由于无法显示title，不做添加
//		// 根据sort排序
//		ArrayList<Map.Entry<String, Annotation[]>> result = new ArrayList<Map.Entry<String, Annotation[]>>();
//		Map<String, Annotation[]> propMap = getAnnosGroupingByPropName(clz);
//		for (Map.Entry<String, Annotation[]> entry : propMap.entrySet()) {
//			result.add(entry);
//		}
//		Collections.sort(result,
//				new java.util.Comparator<Map.Entry<String, Annotation[]>>() {
//					public int compare(Entry<String, Annotation[]> e1,
//							Entry<String, Annotation[]> e2) {
//						PropInfo info1 = getAnnotation(e1.getValue(),
//								PropInfo.class);
//						PropInfo info2 = getAnnotation(e2.getValue(),
//								PropInfo.class);
//						if (info1 == null && info2 == null)
//							return 0;
//						if (info1 == null)
//							return 1;
//						if (info2 == null)
//							return -1;
//						return info1.sort() - info2.sort();
//					}
//				});
//		return result;
//	}
//
//	/**
//	 * 根据bean的类中的注解把bean中的内容填充到表单里面去，
//	 * <p>
//	 * 如果指定propNames不为空则只绑定这些属性，这个属性名是指javaBean中的属性名，不是表单名.
//	 * 绑定的时候必须有位置属性，如果没有的话，相关的元素将被忽略，除非是HIDDEN。
//	 * 和一般的FormPanel不一样，在GridLayoutFormPanel因为有位置属性，会强行覆盖原有的内容 所以一般建议只对空表单操作
//	 * </p>
//	 * 
//	 * @param form
//	 *            GridLayoutFormPanel
//	 * @param bean
//	 *            Object
//	 * @param propNames
//	 *            如果指定的属性名不为空则只绑定这些属性
//	 */
//	public static void bind(GridLayoutFormPanel form, Object bean,
//			String... propNames) {
//		if (bean == null)
//			return;
//		HashSet<String> limitProps = null;
//		if (propNames != null && propNames.length > 0) {
//			limitProps = new HashSet<String>(Arrays.asList(propNames));
//		}
//		List<Map.Entry<String, Annotation[]>> properties = sortProperties(bean
//				.getClass());
//		for (Map.Entry<String, Annotation[]> entry : properties) {
//			if (limitProps != null && !limitProps.contains(entry.getKey())) {
//				continue;
//			}
//			PropInfo info = getAnnotation(entry.getValue(), PropInfo.class);
//			GridPosition pos = getAnnotation(entry.getValue(),
//					GridPosition.class);
//			FormElement<?> fe = null;
//			if (info != null && pos != null) {
//				String formElmentName = info.name();
//				if (formElmentName == null || formElmentName.equals("")) {
//					formElmentName = entry.getKey();
//				}
//				// 每个PropInfo 如果它已经有formElement，那么设置值，格式，和校验信息
//				fe = form.findSingleElementByName(formElmentName);
//				// 如果没有新增加一个formElement
//				if (fe == null) {
//					// 新增属性
//					FormElementType t = info.formType();
//					Class<?> c = getPropType(bean.getClass(), entry.getKey());
//					if (t == FormElementType.AUTO) {
//						// 自动决定属性
//						if (Date.class.isAssignableFrom(c)) {
//							t = FormElementType.DATEPICKER;
//						} else if (Number.class.isAssignableFrom(c)
//								|| int.class == c || long.class == c
//								|| short.class == c || double.class == c
//								|| float.class == c) {
//							t = FormElementType.SPINNER;
//						} else {
//							t = FormElementType.TEXT;
//						}
//					}
//
//					switch (t) {
//					case AUTO:
//						break;
//					case TEXT:
//						fe = new Text(formElmentName, info.title(), null, -1);
//						break;
//					case TEXTAREA:
//						fe = new Textarea(formElmentName, info.title(), null,
//								-1);
//						break;
//					case SPINNER:
//						fe = new Spinner(formElmentName, info.title(), null,
//								null, null, new Double(1.0));
//						break;
//					case DATEPICKER:
//						Format format = getAnnotation(entry.getValue(),
//								Format.class);
//						int formatValue = DatePicker.DATE_TIME_FULL;
//						if (format != null) {
//							String formatStr = format.formFormat();
//							if (formatStr == null || formatStr.equals("")) {
//								formatStr = format.format();
//							}
//							if ("yyyy-MM-dd".equals(formatStr)) {
//								formatValue = DatePicker.DATE;
//							} else if ("yyyy-MM-dd HH:mm".equals(formatStr)) {
//								formatValue = DatePicker.DATE_TIME;
//							}
//						}
//						fe = new DatePicker(formElmentName, info.title(), null,
//								formatValue);
//						break;
//
//					case HIDDEN:
//						// fe = new Hidden(formElmentName, getPorpValue(bean,
//						// propName));
//						break;
//					case LABEL:
//						fe = new Label(formElmentName, info.title(), null);
//						break;
//					}
//					if (t == FormElementType.HIDDEN) {
//						form.add(new Hidden(formElmentName, getPropValue(bean,
//								entry.getKey())));
//					} else if (pos.toCol() < 0 && pos.toRow() < 0) {
//							form.add(pos.row(), pos.col(), fe);
//					} else if (pos.toCol() < 0) {
//						form.add(pos.row(), pos.col(), pos.toRow(), pos
//								.col(), fe);
//					} else if (pos.toRow() < 0) {
//						form.add(pos.row(), pos.col(), pos.row(), pos
//								.toCol(), fe);
//					} else {
//						form.add(pos.row(), pos.col(), pos.toRow(), pos
//								.toCol(), fe);
//					}
//				}
//			} else if (info != null) {
//				String formElmentName = info.name();
//				if (formElmentName == null || formElmentName.equals("")) {
//					formElmentName = entry.getKey();
//				}
//				// 每个PropInfo 如果它已经有formElement，那么设置值，格式，和校验信息
//				fe = form.findSingleElementByName(formElmentName);
//				if (fe == null) {
//					form.add(new Hidden(formElmentName, getPropValue(bean,
//							entry.getKey())));
//				}
//			} else {
//				// 如果PropInfo信息没有的话。
//				fe = form.findSingleElementByName(entry.getKey());
//				if (fe == null) {
//					form.add(new Hidden(entry.getKey(), getPropValue(bean,
//							entry.getKey())));
//				}
//				// 没有设置PropInfo的属性，由于不能确定其位置不能自动添加，但是可以设置值和校验信息
//			}
//			// System.out.println("entry.getKey()="+entry.getKey()+"\t
//			// fe="+(fe==null?"null":fe.getName()));
//			if (fe != null) {
//				setAnnotation(fe, bean, entry.getKey(), entry.getValue());
//			}
//		}
//	}
//
//	/**
//	 * 根据bean的类中的注解把bean中的内容填充到Grid里面去，
//	 * <p>
//	 * 如果指定propNames不为空则只绑定这些属性，这个属性名是指javaBean中的属性名，不是表单名.
//	 * </p>
//	 * 
//	 * @param grid
//	 *            GridLayoutFormPanel
//	 * @param data
//	 *            Collection<?>
//	 * @param clz
//	 *            Class 如果这个collection为空则取不到类型，那么需要制定类型进行一个空表格(仅表头)的绑定
//	 * @param propNames
//	 *            如果指定的属性名不为空则只绑定这些属性
//	 */
//	public static void bind(GridPanel grid, Collection<?> data, Class<?> clz,
//			String... propNames) {
//
//		HashSet<String> limitProps = null;
//		if (propNames != null && propNames.length > 0) {
//			limitProps = new HashSet<String>(Arrays.asList(propNames));
//		}
//		List<Map.Entry<String, Annotation[]>> properties = sortProperties(clz);
//		// 这里理论上要检查是否有format对象。然后再设置
//		Collection<?> decorateData = decorate(data, clz, properties, limitProps);
//		grid.setData(decorateData);
//		int index = 0;
//		for (Map.Entry<String, Annotation[]> entry : properties) {
//			if (limitProps != null && !limitProps.contains(entry.getKey())) {
//				continue;
//			}
//			PropInfo info = getAnnotation(entry.getValue(), PropInfo.class);
//			if (info == null) {
//				// 必须绑定成hidden
//
//				if (decorateData == data) {// 原始数据使用原始模式
//					grid.addColumn(GridColumn.hidden(entry.getKey(), entry
//							.getKey()));
//				} else {
//					grid.addColumn(GridColumn.hidden(index, entry.getKey()));
//				}
//			} else {
//
//				GridColumnType t = info.gridType();
//				String beanProp = entry.getKey();
//				String xmlProp = info.gridName();
//				if (xmlProp == null || xmlProp.equals("")) {
//					xmlProp = beanProp;
//				}
//				String title = info.title();
//				String width = info.gridWidth();
//				switch (t) {
//				case HIDDEN:
//					if (decorateData == data) {// 原始数据使用原始模式
//						grid.addColumn(GridColumn.hidden(beanProp, entry
//								.getKey()));
//					} else {
//						grid
//								.addColumn(GridColumn.hidden(index, entry
//										.getKey()));
//					}
//					break;
//				case RADIO:
//					if (decorateData == data) {// 原始数据使用原始模式
//						grid.addColumn(GridColumn.hidden(beanProp, entry
//								.getKey()));
//					} else {
//						grid
//								.addColumn(GridColumn.hidden(index, entry
//										.getKey()));
//					}
//					grid.addColumn(GridColumn.radio(xmlProp, width));
//					break;
//				case CHECKBOX:
//					if (decorateData == data) {// 原始数据使用原始模式
//						grid.addColumn(GridColumn.hidden(beanProp, entry
//								.getKey()));
//					} else {
//						grid
//								.addColumn(GridColumn.hidden(index, entry
//										.getKey()));
//					}
//					grid.addColumn(GridColumn.checkbox(xmlProp, width));
//					break;
//				default:
//					if (decorateData == data) {// 原始数据使用原始模式
//						grid.addColumn(GridColumn.text(beanProp, xmlProp,
//								title, width));
//					} else {
//						grid.addColumn(GridColumn.text(index, xmlProp, title,
//								width));
//					}
//					break;
//				}
//			}
//			index++;
//		}
//	}
//
//	private static Collection<?> decorate(Collection<?> data, Class<?> clz,
//			List<Entry<String, Annotation[]>> properties,
//			HashSet<String> limitProps) {
//		if (data == null || data.size() == 0)
//			return data;
//		// 如果有format类。并且效果和默认的格式不一样，那么使用这个格式进行装饰这个data，否则返回原data
//		boolean needDecoration = false;
//		for (Entry<String, Annotation[]> entry : properties) {
//			if (limitProps != null && !limitProps.contains(entry.getKey())) {
//				continue;
//			}
//			Format format = getAnnotation(entry.getValue(), Format.class);
//			if (format != null
//					&& !format.format().equals("yyyy-MM-dd HH:mm:ss")) {
//				needDecoration = true;
//				break;
//			}
//		}
//		if (!needDecoration)
//			return data;
//		List<Object[]> decorateData = new ArrayList<Object[]>(data.size());
//		for (Object o : data) {
//			List<Object> row = new ArrayList<Object>();
//			for (Entry<String, Annotation[]> entry : properties) {
//				if (limitProps != null && !limitProps.contains(entry.getKey())) {
//					continue;
//				}
//				Format format = getAnnotation(entry.getValue(), Format.class);
//				if (format == null) {
//					row.add(getPropValue(o, entry.getKey()));
//				} else {
//					Class<?> type = getPropType(clz, entry.getKey());
//					try {
//						Object propValue = getPropValue(o, entry.getKey());
//						if (java.util.Date.class.isAssignableFrom(type)) {
//							// 时间
//							SimpleDateFormat SDF = new SimpleDateFormat(format
//									.format());
//							row.add(SDF.format(propValue));
//						} else {
//							// 数字
//							DecimalFormat DF = new DecimalFormat(format
//									.format());
//							row.add(DF.format(propValue));
//						}
//					} catch (Exception ex) {
//						row.add(null);
//						ex.printStackTrace();
//					}
//				}
//			}
//			decorateData.add(row.toArray());
//		}
//		return decorateData;
//	}
//
//	/**
//	 * 把request里面的内容绑定到javabean中。 如果有strict校验,将根据规则检测
//	 * 如果没有strict校验，但是数据不合法，也将当做校验错误 通过校验后，如果是时间数据类型，还会根据format进行解析。
//	 * 该做法将会把所有错误信息都在result的errorMessages中 所以如果errorMessages 有内容的时候
//	 * result的信息时不完整的。
//	 * 
//	 * @param bean
//	 *            不能为空否则取不到Class
//	 * @param request
//	 *            HttpServletRequest
//	 * @return 校验结果List<String> 如果为空或长度为0则没有校验信息错误.如果不是则bean的信息可能不完整
//	 */
//	public static List<String> bind(Object bean, HttpServletRequest request) {
//		return bind(bean,request,"default");
//	}
//	/**
//	 * 把request里面的内容绑定到javabean中。 如果有strict校验,将根据规则检测
//	 * 如果没有strict校验，但是数据不合法，也将当做校验错误 通过校验后，如果是时间数据类型，还会根据format进行解析。
//	 * 该做法将会把所有错误信息都在result的errorMessages中 所以如果errorMessages 有内容的时候
//	 * result的信息时不完整的。
//	 * 
//	 * @param bean
//	 *            不能为空否则取不到Class
//	 * @param request
//	 *            HttpServletRequest
//	 * @param validateGroup String 校验用的组策略，默认为default
//	 * @return 校验结果List<String> 如果为空或长度为0则没有校验信息错误.如果不是则bean的信息可能不完整
//	 */
//	public static List<String> bind(Object bean, HttpServletRequest request,String validateGroup) {
//		if (bean == null)
//			return null;
//		ArrayList<String> errMsgs = new ArrayList<String>();
//		List<Map.Entry<String, Annotation[]>> properties = sortProperties(bean
//				.getClass());
//		for (Map.Entry<String, Annotation[]> entry : properties) {
//			String formName = entry.getKey();
//			String propName = entry.getKey();
//			String title = entry.getKey();
//			PropInfo propInfo = getAnnotation(entry.getValue(), PropInfo.class);
//			if (propInfo != null && propInfo.name() != null
//					&& !propInfo.name().equals("")) {
//				formName = propInfo.name();
//			}
//			if (propInfo != null && propInfo.title() != null
//					&& !propInfo.title().equals("")) {
//				title = propInfo.title();
//			}
//
//			String[] values = request.getParameterValues(formName);
//			String valueStr = null;
//			if (values == null || values.length == 0||values[0]==null||values[0].equals("")) {
//				// 没有数值的话，值触发非检查
//				NotNull notnullCheck = getAnnotation(entry.getValue(),
//						NotNull.class);
//				
//				//需要考虑是不是这个组别的
//				if (notnullCheck != null && notnullCheck.strict()&&containGroup(notnullCheck.groups(),validateGroup)) {
//					String errMsg = notnullCheck.message();
//					if (errMsg != null && !errMsg.equals("")) {
//						errMsgs.add(errMsg.replace("${t}", title));
//					} else {
//						errMsgs.add(title + " must not empty");
//					}
//				}
//				continue;// 没有数值
//			}
//			if (values.length == 1) {
//				valueStr = Utils.getParameter(request, formName);// 防止tomcat的BUG
//			} else {
//				StringBuilder sb = new StringBuilder();
//				for (String v : values) {
//					sb.append(v).append(',');
//				}
//				valueStr = sb.substring(0, sb.length() - 1);
//			}
//			Class<?> targetClz = getPropType(bean.getClass(), propName);
//			Object value = null;
//			if (String.class == targetClz) {
//				value = valueStr;
//			} else if (Boolean.class == targetClz || boolean.class == targetClz) {
//				if ("1".equals(valueStr) || "true".equalsIgnoreCase(valueStr)) {
//					value = true;
//				} else if ("0".equals(valueStr)
//						|| "false".equalsIgnoreCase(valueStr)) {
//					value = false;
//				} else {
//					errMsgs.add(title + " is not well-formed Boolean type.");
//				}
//			} else if (Date.class.isAssignableFrom(targetClz)) {
//				Format format = getAnnotation(entry.getValue(), Format.class);
//				if (format != null && format.format() != null
//						&& format.format().equals("")) {
//					try {
//						SimpleDateFormat SDF = new SimpleDateFormat(format
//								.format());
//						value = SDF.parse(valueStr);
//					} catch (Exception ex) {}
//				}
//				if (value == null) {
//					String[] formats = new String[] { "yyyy-MM-dd HH:mm:ss",
//							"yyyy-MM-dd HH:mm", "yyyy-MM-dd" };
//					for (String f : formats) {
//						try {
//							SimpleDateFormat SDF = new SimpleDateFormat(f);
//							value = SDF.parse(valueStr);
//						} catch (Exception ex) {
//						}
//						if (value != null)
//							break;
//					}
//				}
//				if (value == null) {
//					errMsgs.add(title + " is not well-formed Date type.");
//				}
//			} else if (long.class == targetClz || Long.class == targetClz) {
//				// 该format一般不生效所以默认按无format计息
//				try {
//					value = Long.parseLong(valueStr);
//				} catch (Exception ex) {
//					Format format = getAnnotation(entry.getValue(),
//							Format.class);
//					if (format != null && format.format() != null
//							&& format.format().equals("")) {
//						try {
//							DecimalFormat DF = new DecimalFormat(format
//									.format());
//							Number n = DF.parse(valueStr);
//							value = n.longValue();
//						} catch (Exception ex2) {
//						}
//					}
//				}
//				if (value == null) {
//					errMsgs.add(title + " is not well-formed long/Long type.");
//				}
//			} else if (double.class == targetClz || Double.class == targetClz) {
//				try {
//					value = Double.parseDouble(valueStr);
//				} catch (Exception ex) {
//					Format format = getAnnotation(entry.getValue(),
//							Format.class);
//					if (format != null && format.format() != null
//							&& format.format().equals("")) {
//						try {
//							DecimalFormat DF = new DecimalFormat(format
//									.format());
//							Number n = DF.parse(valueStr);
//							value = n.doubleValue();
//						} catch (Exception ex2) {
//						}
//					}
//				}
//				if (value == null) {
//					errMsgs.add(title
//							+ " is not well-formed double/Double type.");
//				}
//			} else if (int.class == targetClz || Integer.class == targetClz) {
//				try {
//					value = Integer.parseInt(valueStr);
//				} catch (Exception ex) {
//					Format format = getAnnotation(entry.getValue(),
//							Format.class);
//					if (format != null && format.format() != null
//							&& format.format().equals("")) {
//						try {
//							DecimalFormat DF = new DecimalFormat(format
//									.format());
//							Number n = DF.parse(valueStr);
//							value = n.intValue();
//						} catch (Exception ex2) {
//						}
//					}
//				}
//				if (value == null) {
//					errMsgs
//							.add(title
//									+ " is not well-formed int/Integer type.");
//				}
//			} else if (short.class == targetClz || Short.class == targetClz) {
//				try {
//					value = Short.parseShort(valueStr);
//				} catch (Exception ex) {
//					Format format = getAnnotation(entry.getValue(),
//							Format.class);
//					if (format != null && format.format() != null
//							&& format.format().equals("")) {
//						try {
//							DecimalFormat DF = new DecimalFormat(format
//									.format());
//							Number n = DF.parse(valueStr);
//							value = n.shortValue();
//						} catch (Exception ex2) {
//						}
//					}
//				}
//				if (value == null) {
//					errMsgs
//							.add(title
//									+ " is not well-formed short/Short type.");
//				}
//			} else if (float.class == targetClz || Float.class == targetClz) {
//				try {
//					value = Float.parseFloat(valueStr);
//				} catch (Exception ex) {
//					Format format = getAnnotation(entry.getValue(),
//							Format.class);
//					if (format != null && format.format() != null
//							&& format.format().equals("")) {
//						try {
//							DecimalFormat DF = new DecimalFormat(format
//									.format());
//							Number n = DF.parse(valueStr);
//							value = n.floatValue();
//						} catch (Exception ex2) {
//						}
//					}
//				}
//				if (value == null) {
//					errMsgs
//							.add(title
//									+ " is not well-formed float/Float type.");
//				}
//			}
//			if (value == null) {
//				continue;
//			}
//
//			setPropValue(bean, propName, value);
//			validateProperty(errMsgs, value, title, entry.getValue(),validateGroup);
//		}
//
//		return errMsgs;
//	}
//
//	private static boolean containGroup(String[] groups, String validateGroup) {
//		if(validateGroup==null)return true;
//		if(groups==null||groups.length==0){
//			groups=new String[]{"default"};
//		}
//		for(String g:groups){
//			if(validateGroup.equals(g))return true;
//		}
//		return false;
//	}
//
//	private static void validateProperty(List<String> errMsgs, Object value,
//			String title, Annotation[] annos,String validateGroup) {
//		// 如果有严格校验
//		List<String> originalMsg = new ArrayList<String>();
//		Decimal decimalCheck = getAnnotation(annos, Decimal.class);
//		if (decimalCheck != null && decimalCheck.strict()&&containGroup(decimalCheck.groups(),validateGroup)) {
//			//需要考虑是不是这个组别的
//			Number cast = (Number) value;
//			boolean pass = true;
//			if (pass && decimalCheck.max() != Integer.MAX_VALUE) {
//				pass = cast.doubleValue() <= decimalCheck.max();
//			}
//			if (pass && decimalCheck.min() != Integer.MIN_VALUE) {
//				pass = cast.doubleValue() >= decimalCheck.min();
//			}
//			if (!pass) {
//				String errMsg = decimalCheck.message();
//				if (errMsg != null && !errMsg.equals("")) {
//					originalMsg.add(errMsg.replace("${mxv}",
//							String.valueOf(decimalCheck.max())).replace(
//							"${mnv}", String.valueOf(decimalCheck.min())));
//				} else {
//					if (decimalCheck.max() != Integer.MAX_VALUE
//							&& decimalCheck.min() != Integer.MIN_VALUE) {
//						originalMsg.add("${t} must between "
//								+ decimalCheck.min() + " and "
//								+ decimalCheck.max());
//					} else if (decimalCheck.max() != Integer.MAX_VALUE) {
//						originalMsg.add("${t} must not greater than "
//								+ decimalCheck.max());
//					} else if (decimalCheck.min() != Integer.MIN_VALUE) {
//						originalMsg.add("${t} must not less than "
//								+ decimalCheck.min());
//					}
//
//				}
//			}
//		}
//		Length lengthCheck = getAnnotation(annos, Length.class);
//		if (lengthCheck != null && lengthCheck.strict()&&containGroup(lengthCheck.groups(),validateGroup)) {
//			String cast = (String) value;
//			boolean pass = true;
//			if (pass && lengthCheck.max() != Integer.MAX_VALUE) {
//				pass = cast.length() <= lengthCheck.max();
//			}
//			if (pass && lengthCheck.min() != Integer.MIN_VALUE) {
//				pass = cast.length() >= lengthCheck.min();
//			}
//			if (!pass) {
//				String errMsg = lengthCheck.message();
//				if (errMsg != null && !errMsg.equals("")) {
//					originalMsg.add(errMsg.replace("${mxl}",
//							String.valueOf(lengthCheck.max())).replace(
//							"${mnl}", String.valueOf(lengthCheck.min())));
//				} else {
//					if (lengthCheck.max() != Integer.MAX_VALUE
//							&& lengthCheck.min() != Integer.MIN_VALUE) {
//						originalMsg.add("${t} length must between "
//								+ lengthCheck.min() + " and "
//								+ lengthCheck.max());
//					} else if (lengthCheck.max() != Integer.MAX_VALUE) {
//						originalMsg.add("${t} length must not greater than "
//								+ lengthCheck.max());
//					} else if (lengthCheck.min() != Integer.MIN_VALUE) {
//						originalMsg.add("${t} length must not less than "
//								+ lengthCheck.min());
//					}
//				}
//			}
//		}
//		Pattern patternCheck = getAnnotation(annos, Pattern.class);
//		if (patternCheck != null && patternCheck.strict()) {
//			// FIXME 暂时无法再JAVA中进行JS的patternCheck
//		}
//		Size sizeCheck = getAnnotation(annos, Size.class);
//		if (sizeCheck != null && sizeCheck.strict()&&containGroup(sizeCheck.groups(),validateGroup)) {
//			String cast = (String) value;
//			boolean pass = true;
//			if (pass && sizeCheck.max() != Integer.MAX_VALUE) {
//				pass = cast.length() <= sizeCheck.max();
//			}
//			if (pass && sizeCheck.min() != Integer.MIN_VALUE) {
//				pass = cast.length() >= sizeCheck.min();
//			}
//			if (!pass) {
//				String errMsg = sizeCheck.message();
//				if (errMsg != null && !errMsg.equals("")) {
//					originalMsg.add(errMsg.replace("${mxs}",
//							String.valueOf(sizeCheck.max())).replace("${mns}",
//							String.valueOf(sizeCheck.min())));
//				} else {
//					if (sizeCheck.max() != Integer.MAX_VALUE
//							&& sizeCheck.min() != Integer.MIN_VALUE) {
//						originalMsg.add("${t} size must between "
//								+ sizeCheck.min() + " and " + sizeCheck.max());
//					} else if (sizeCheck.max() != Integer.MAX_VALUE) {
//						originalMsg.add("${t} size must not greater than "
//								+ sizeCheck.max());
//					} else if (sizeCheck.min() != Integer.MIN_VALUE) {
//						originalMsg.add("${t} size must not less than "
//								+ sizeCheck.min());
//					}
//				}
//			}
//		}
//		Time timeCheck = getAnnotation(annos, Time.class);
//		if (timeCheck != null && timeCheck.strict()&&containGroup(timeCheck.groups(),validateGroup)) {
//			Date cast = (Date) value;
//			boolean pass = true;
//
//			if (pass && timeCheck.max() != null) {
//				pass = !getTime(timeCheck.max()).before(cast);
//			}
//			if (pass && timeCheck.min() != null) {
//				pass = !getTime(timeCheck.min()).after(cast);
//			}
//			if (!pass) {
//				String errMsg = timeCheck.message();
//				if (errMsg != null && !errMsg.equals("")) {
//					originalMsg.add(errMsg.replace("${mxt}", timeCheck.max())
//							.replace("${mnt}", timeCheck.min()));
//				} else {
//					if (timeCheck.max() != null && timeCheck.min() != null) {
//						originalMsg.add("${t} size must between "
//								+ timeCheck.min() + " and " + timeCheck.max());
//					} else if (timeCheck.max() != null) {
//						originalMsg.add("${t} size must not greater than "
//								+ timeCheck.max());
//					} else if (timeCheck.min() != null) {
//						originalMsg.add("${t} size must not less than "
//								+ timeCheck.min());
//					}
//				}
//			}
//		}
//		for (String s : originalMsg) {
//			errMsgs.add(s.replace("${t}", title));
//		}
//	}
//
//	@SuppressWarnings("unchecked")
//	private static <T extends Annotation> T getAnnotation(Annotation[] annos, Class<T> c) {
//		if (annos == null)
//			return null;
//		for (Annotation anno : annos) {
//			if (anno.annotationType() == c) {
//				return (T) anno;
//			}
//		}
//		return null;
//	}
//
////	/**
////	 * 
////	 * @param <T>
////	 * @param clz
////	 * @param propName
////	 * @param annotationClass
////	 * @return
////	 */
////	public static <T extends Annotation> T getAnnotation(Class<?> clz,
////			String propName, Class<T> annotationClass) {
////		Map<String, Annotation[]> allAnnos = getAnnosGroupingByPropName(clz);
////		Annotation[] propAnnos = allAnnos.get(propName);
////		return getAnnotation(propAnnos, annotationClass);
////	}
//
//	/**
//	 * 取得某个类的所有属性的注解 每个属性的注解可以写在属性上，也可以写在getter和setter上。但只能写一处，读取到一处，则后面的注解失效。
//	 * 
//	 * @param c 类
//	 * @return Map&lt;String,Annotation[]&gt;
//	 */
//	public static Map<String, Annotation[]> getAnnosGroupingByPropName(
//			Class<?> c) {
//		Map<String, Annotation[]> cachedResult = CACHE.get(c);
//		if (cachedResult != null) {
//			return cachedResult;
//		}
//		// 取到所有的属性名 或疑似属性名比如有isOk但没ok属性的。排除getClass
//		Set<String> propNames = getPropNames(c);
//		// 根据属性名取得注解，注解的优先级别为 属性本身/getter方法/setter方法
//		HashMap<String, Annotation[]> result = new HashMap<String, Annotation[]>();
//		for (String pn : propNames) {
//			Annotation[] annos = null;
//			Field[] fields = c.getDeclaredFields();
//			for (Field f : fields) {
//				if (f.getName().equals(pn)) {
//					annos = f.getAnnotations();
//				}
//			}
//			Method[] methods = c.getDeclaredMethods();
//			if (annos == null || annos.length == 0) {
//				char ch = pn.charAt(0);
//				String getterName = "get" + (char) (ch - 32) + pn.substring(1);
//				for (Method f : methods) {
//					if (f.getName().equals(getterName)) {
//						annos = f.getAnnotations();
//					}
//				}
//			}
//			if (annos == null || annos.length == 0) {
//				char ch = pn.charAt(0);
//				String getterName = "is" + (char) (ch - 32) + pn.substring(1);
//				for (Method f : methods) {
//					if (f.getName().equals(getterName)) {
//						annos = f.getAnnotations();
//					}
//				}
//			}
//			if (annos == null || annos.length == 0) {
//				char ch = pn.charAt(0);
//				String getterName = "set" + (char) (ch - 32) + pn.substring(1);
//				for (Method f : methods) {
//					if (f.getName().equals(getterName)) {
//						annos = f.getAnnotations();
//					}
//				}
//			}
//
//			// if(annos!=null&&annos.length>0){
//			result.put(pn, annos);
//			// }
//		}
//		CACHE.put(c, result);
//		return result;
//	}
//
//	/**
//	 * 取得某个属性的类型，如果无法成功确认，将返回null
//	 * @param c 类
//	 * @param propName 属性名
//	 * @return Class
//	 */
//	public static Class<?> getPropType(Class<?> c, String propName) {
//
//		try {
//			Field f = c.getDeclaredField(propName);
//			if (f != null && f.isAccessible()) {
//				return f.getType();
//			}
//		} catch (Exception ex) { }
//
//		char ch = propName.charAt(0);
//		String partName = (char) (ch - 32) + propName.substring(1);
//		Method getterMethod = null;
//		try {
//			getterMethod = c.getMethod("get" + partName, NO_PARAM_TYPE);
//		} catch (Exception ex) {}
//		if (getterMethod == null) {
//			try {
//				getterMethod = c.getMethod("is" + partName, NO_PARAM_TYPE);
//			} catch (Exception ex) {}
//		}
//		if (getterMethod != null
//				&& Modifier.isPublic(getterMethod.getModifiers())) {
//			return getterMethod.getReturnType();
//		}
//		Method[] methods = c.getDeclaredMethods();
//		if (methods != null) {
//			for (Method m : methods) {
//				if (Modifier.isPublic(m.getModifiers())) {
//					String methodName = m.getName();
//					// 如果是get开头或者is开头，接下来的字母是大写,并且没有参数的方法。
//					// 疑似getter则提取属性名
//					// 如果是set开头接下来的字母是大写,并且自由一个参数
//					// 疑似setter则提取属性名
//					if (m.getParameterTypes() != null
//							&& m.getParameterTypes().length == 1) {
//						if (methodName.equals("set" + partName)) {
//							return m.getParameterTypes()[0];
//						}
//					}
//				}
//			}
//		}
//		return null;
//	}
//
//
//	private static void setPropValue(Object obj, String propName, Object value) {
//		if (obj == null)
//			return;
//		Class<?> c = obj.getClass();
//		try {
//			Field f = c.getDeclaredField(propName);
//			if (f != null && f.isAccessible()) {
//				f.set(obj, value);
//			}
//		} catch (Exception ex) {
//			ex.printStackTrace();
//		}
//		char ch = propName.charAt(0);
//		String partName = (char) (ch - 32) + propName.substring(1);
//		Method setterMethod = null;
//		try {
//			setterMethod = c.getMethod("set" + partName, new Class[]{value.getClass()});
//		} catch (Exception ex) {
//		}
//		if (setterMethod != null
//				&& Modifier.isPublic(setterMethod.getModifiers())) {
//			try {
//				setterMethod.invoke(obj, value);
//			} catch (Exception ex) {
//				ex.printStackTrace();
//			}
//			return;
//		}
//	}
//
//	/**
//	 * 取得属性值
//	 * @param obj 类
//	 * @param propName 属性名
//	 * @return Object
//	 */
//	public static Object getPropValue(Object obj, String propName) {
//		try {
//			if (obj == null)
//				return null;
//			Class<?> c = obj.getClass();
//			try {
//				Field f = c.getDeclaredField(propName);
//				if (f != null && f.isAccessible()) {
//					return f.get(obj);
//				}
//			} catch (Exception ex) {}
//			Method getterMethod = null;
//			char ch = propName.charAt(0);
//			String partName = (char) (ch - 32) + propName.substring(1);
//			try {
//				getterMethod = c.getMethod("get" + partName, NO_PARAM_TYPE);
//			} catch (Exception ex) {}
//			if (getterMethod == null) {
//				try {
//					getterMethod = c.getMethod("is" + partName, NO_PARAM_TYPE);
//				} catch (Exception ex) {}
//			}
//			if (getterMethod != null
//					&& Modifier.isPublic(getterMethod.getModifiers())) {
//				return getterMethod.invoke(obj,NO_PARAM);
//			}
//		} catch (Exception ex) {}
//		return null;
//	}
//
//	/**
//	 * 取到所有的属性名 或疑似属性名
//	 * 比如有isOk但没ok属性的它看起来应该是有ok属性，这样的设置是为了能够检查出代理类的疑似属性。
//	 * 排除getClass
//	 * @param c 类
//	 * @return 属性名
//	 */
//	public static Set<String> getPropNames(Class<?> c) {
//		TreeSet<String> result = new TreeSet<String>();
//		Field[] fields = c.getDeclaredFields();
//		if (fields != null) {
//			for (Field f : fields) {
//				if (f.isAccessible())
//					result.add(f.getName());
//			}
//		}
//		Method[] methods = c.getDeclaredMethods();
//		if (methods != null) {
//			for (Method m : methods) {
//				if (Modifier.isPublic(m.getModifiers())) {
//					String methodName = m.getName();
//
//					// 如果是get开头或者is开头，接下来的字母是大写,并且没有参数的方法。
//					// 疑似getter则提取属性名
//					// 如果是set开头接下来的字母是大写,并且自由一个参数
//					// 疑似setter则提取属性名
//					if (m.getParameterTypes() == null
//							|| m.getParameterTypes().length == 0) {
//						if (methodName.startsWith("get")) {
//							getPropFromGetterName(result, methodName
//									.substring(3));
//						}
//						if (methodName.startsWith("is")) {
//							getPropFromGetterName(result, methodName
//									.substring(2));
//						}
//					}
//					if (m.getParameterTypes() != null
//							&& m.getParameterTypes().length == 1) {
//						if (methodName.startsWith("set")) {
//							getPropFromGetterName(result, methodName
//									.substring(3));
//						}
//					}
//				}
//			}
//		}
//		result.remove("class");
//		return result;
//	}
//
//	private static void getPropFromGetterName(Set<String> result, String str) {
//		// 首先它的长度应该大于0.
//		// 它第一个字母应该是大写
//		// 第一个转化成小写
//		if (str.length() == 0)
//			return;
//		char c = str.charAt(0);
//		if (c < 'A' || c > 'Z') {
//			return;
//		}
//		result.add((char) (c + 32) + str.substring(1));
//	}
//
//	private static void setAnnotation(FormElement<?> input, Object bean,
//			String propName, Annotation[] annos) {
//		// 把值，校验，格式等信息绑定到原有元素中去。
//		// 但如果是HIDDEN或LABEL不绑定校验。
//
//		// FIXME select和checkbox如果有多选的情况
//		input.setValue(getPropValue(bean, propName));
//		if (input instanceof InputFrag<?>) {
//			InputFrag<?> cast = (InputFrag<?>) input;
//			// 添加校验
//			NotNull ntn = getAnnotation(annos, NotNull.class);
//			if (ntn != null) {
//				String errMsg = ntn.message();
//				if ("".equals(errMsg))
//					errMsg = null;
//				//如果ntn的策略组包含default 应该同时表示红色星号
//				if(ntn.groups()==null||ntn.groups().length==0||
//						Arrays.asList(ntn.groups()).contains("default")){
//					cast.setNotnull(true);
//				}
//				cast.addNotNullValidate(true, errMsg, ntn.groups());
//			}
//			Pattern pattern = getAnnotation(annos, Pattern.class);
//			if (pattern != null) {
//				String errMsg = pattern.message();
//				if ("".equals(errMsg))
//					errMsg = null;
//				String patternStr = pattern.pattern();
//				if ("".equals(patternStr))
//					patternStr = null;
//				cast.addPatternValidate(patternStr, errMsg, pattern.groups());
//			}
//			Decimal decimal = getAnnotation(annos, Decimal.class);
//			if (decimal != null) {
//				String errMsg = decimal.message();
//				if ("".equals(errMsg))
//					errMsg = null;
//				Integer minValue = decimal.min() == Integer.MIN_VALUE ? null
//						: decimal.min();
//				Integer maxValue = decimal.max() == Integer.MAX_VALUE ? null
//						: decimal.max();
//				cast.addDecimalValidate(minValue, maxValue, errMsg, decimal
//						.groups());
//			}
//			Length length = getAnnotation(annos, Length.class);
//			if (length != null) {
//				String errMsg = length.message();
//				if ("".equals(errMsg))
//					errMsg = null;
//				Integer minValue = length.min() < 0 ? null : length.min();
//				Integer maxValue = length.max() < 0 ? null : length.max();
//				cast.addLengthValidate(minValue, maxValue, errMsg, length
//						.groups());
//			}
//			Size size = getAnnotation(annos, Size.class);
//			if (size != null) {
//				String errMsg = size.message();
//				if ("".equals(errMsg))
//					errMsg = null;
//				Integer minValue = size.min() < 0 ? null : size.min();
//				Integer maxValue = size.max() < 0 ? null : size.max();
//				cast.addSizeValidate(minValue, maxValue, errMsg, size.groups());
//			}
//			Time time = getAnnotation(annos, Time.class);
//			if (time != null) {
//				String errMsg = time.message();
//				if ("".equals(errMsg))
//					errMsg = null;
//				Date minValue = getTime(time.min());
//				Date maxValue = getTime(time.max());
//				cast.addTimeValidate(minValue, maxValue, errMsg, time.groups());
//			}
//
//			// 添加属性
//			if (getAnnotation(annos, Readonly.class) != null) {
//				cast.setReadonly(true);
//			}
//			if (getAnnotation(annos, Disabled.class) != null) {
//				cast.setDisabled(true);
//			}
//		}
//	}
//
//	private static Date getTime(String str) {
//		if (str == null || str.length() == 0)
//			return null;
//		String format = "yyyy-MM-dd HH:mm:ss";
//		if (str.length() == 10) {
//			format = "yyyy-MM-dd";
//		} else if (str.length() == 16) {
//			format = "yyyy-MM-dd HH:mm";
//		}
//		try {
//			SimpleDateFormat SDF = new SimpleDateFormat(format);
//			return SDF.parse(str);
//		} catch (Exception ex) {
//			ex.printStackTrace();
//		}
//		return null;
//	}
//	private static final Class<?>[] NO_PARAM_TYPE = new Class<?>[0];
//	private static final Object[] NO_PARAM = new Object[0];
//
//	private static final HashMap<Class<?>, Map<String, Annotation[]>> CACHE = new HashMap<Class<?>, Map<String, Annotation[]>>();
//
//}
